/*     */ package com.zimbra.cs.service.admin;
/*     */ 
/*     */ import com.google.common.base.Objects;
/*     */ import com.google.common.base.Objects.ToStringHelper;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.AdminConstants;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.MailboxManager;
/*     */ import com.zimbra.cs.mime.Mime.FixedMimeMessage;
/*     */ import com.zimbra.cs.mime.ParsedMessage;
/*     */ import com.zimbra.cs.store.Blob;
/*     */ import com.zimbra.cs.store.MailboxBlob;
/*     */ import com.zimbra.cs.store.StagedBlob;
/*     */ import com.zimbra.cs.store.StoreManager;
/*     */ import com.zimbra.cs.util.JMSession;
/*     */ import com.zimbra.qa.unittest.AccountTestUtil;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import java.io.ByteArrayOutputStream;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.util.ArrayList;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import javax.mail.internet.MimeMessage;
/*     */ import org.apache.commons.lang.RandomStringUtils;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class VerifyStoreManager
/*     */   extends AdminDocumentHandler
/*     */ {
/*     */   private class Stats
/*     */   {
/*     */     int numBlobs;
/*     */     long incomingTime;
/*     */     long stageTime;
/*     */     long linkTime;
/*     */     long fetchTime;
/*     */     long deleteTime;
/*     */     
/*     */     private Stats(int numBlobs, long incomingTime, long stageTime, long linkTime, long fetchTime, long deleteTime)
/*     */     {
/*  66 */       this.numBlobs = numBlobs;
/*  67 */       this.incomingTime = incomingTime;
/*  68 */       this.stageTime = stageTime;
/*  69 */       this.linkTime = linkTime;
/*  70 */       this.fetchTime = fetchTime;
/*  71 */       this.deleteTime = deleteTime;
/*     */     }
/*     */     
/*     */     public String toString()
/*     */     {
/*  76 */       return Objects.toStringHelper(this).add("num blobs", this.numBlobs).add("storeIncoming", this.incomingTime).add("stage", this.stageTime).add("link", this.linkTime).add("fetch", this.fetchTime).add("delete", this.deleteTime).toString();
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*  82 */   private String USER_NAME = "zimbraStoreVerifyUser";
/*     */   
/*     */   private byte[] readInputStream(InputStream is) throws IOException {
/*  85 */     ByteArrayOutputStream baos = new ByteArrayOutputStream();
/*  86 */     int i = -1;
/*  87 */     while ((i = is.read()) >= 0) {
/*  88 */       baos.write(i);
/*     */     }
/*  90 */     return baos.toByteArray();
/*     */   }
/*     */   
/*     */   private boolean bytesEqual(byte[] b1, byte[] b2) {
/*  94 */     if (b1.length != b2.length) {
/*  95 */       return false;
/*     */     }
/*  97 */     for (int i = 0; i < b1.length; i++) {
/*  98 */       if (b1[i] != b2[i]) {
/*  99 */         return false;
/*     */       }
/*     */     }
/* 102 */     return true;
/*     */   }
/*     */   
/*     */   private void assertEquals(String message, Object o1, Object o2) throws Exception
/*     */   {
/* 107 */     if ((o1 == null) && (o2 == null))
/* 108 */       return;
/* 109 */     if ((o1 == null) && (o2 != null))
/* 110 */       throw new Exception("verification failed checking " + message);
/* 111 */     if (!o1.equals(o2)) {
/* 112 */       if (((o1 instanceof Number)) && ((o2 instanceof Number))) {
/* 113 */         Number num1 = (Number)o1;
/* 114 */         Number num2 = (Number)o2;
/* 115 */         if (num1.longValue() == num2.longValue()) {
/* 116 */           return;
/*     */         }
/*     */       }
/* 119 */       throw new Exception("verification failed checking " + message);
/*     */     }
/*     */   }
/*     */   
/*     */   private void assertTrue(String message, boolean condition) throws Exception {
/* 124 */     if (!condition) {
/* 125 */       throw new Exception("verification failed checking " + message);
/*     */     }
/*     */   }
/*     */   
/*     */   private ParsedMessage getMessage(int size) throws Exception {
/* 130 */     MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
/* 131 */     mm.setHeader("From", " Jimmy <jimmy@example.com>");
/* 132 */     mm.setHeader("To", " Janis <janis@example.com>");
/* 133 */     mm.setHeader("Subject", "Hello");
/* 134 */     mm.setHeader("Message-ID", "<sakfuslkdhflskjch@oiwm.example.com>");
/* 135 */     mm.setText("nothing to see here\r\n" + RandomStringUtils.random(size));
/* 136 */     return new ParsedMessage(mm, false);
/*     */   }
/*     */   
/*     */   private void testStore() throws Exception {
/* 140 */     ParsedMessage pm = getMessage(1024);
/* 141 */     byte[] mimeBytes = readInputStream(pm.getRawInputStream());
/*     */     
/* 143 */     Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(AccountTestUtil.getAccount(this.USER_NAME));
/*     */     
/* 145 */     StoreManager sm = StoreManager.getInstance();
/* 146 */     Blob blob = sm.storeIncoming(pm.getRawInputStream());
/*     */     
/* 148 */     assertEquals("blob size = message size", Integer.valueOf(pm.getRawData().length), Long.valueOf(blob.getRawSize()));
/* 149 */     assertTrue("blob content = mime content", bytesEqual(mimeBytes, readInputStream(blob.getInputStream())));
/*     */     
/* 151 */     StagedBlob staged = sm.stage(blob, mbox);
/* 152 */     assertEquals("staged size = blob size", Long.valueOf(blob.getRawSize()), Long.valueOf(staged.getSize()));
/*     */     
/* 154 */     MailboxBlob mblob = sm.link(staged, mbox, 0, 0);
/* 155 */     assertEquals("link size = staged size", Long.valueOf(staged.getSize()), Long.valueOf(mblob.getSize()));
/* 156 */     assertTrue("link content = mime content", bytesEqual(mimeBytes, readInputStream(mblob.getLocalBlob().getInputStream())));
/*     */     
/* 158 */     mblob = sm.getMailboxBlob(mbox, 0, 0, staged.getLocator());
/* 159 */     assertEquals("mblob size = staged size", Long.valueOf(staged.getSize()), Long.valueOf(mblob.getSize()));
/* 160 */     assertTrue("mailboxblob content = mime content", bytesEqual(mimeBytes, readInputStream(mblob.getLocalBlob().getInputStream())));
/*     */     
/* 162 */     sm.delete(mblob);
/*     */   }
/*     */   
/*     */   private void checkBlob(ParsedMessage pm, Blob blob, StagedBlob staged, MailboxBlob linked, MailboxBlob fetched, Mailbox mbox) throws IOException, Exception
/*     */   {
/* 167 */     byte[] mimeBytes = readInputStream(pm.getRawInputStream());
/*     */     
/* 169 */     assertEquals("blob size = message size", Integer.valueOf(pm.getRawData().length), Long.valueOf(blob.getRawSize()));
/* 170 */     assertTrue("blob content = mime content", bytesEqual(mimeBytes, readInputStream(blob.getInputStream())));
/*     */     
/* 172 */     assertEquals("staged size = blob size", Long.valueOf(blob.getRawSize()), Long.valueOf(staged.getSize()));
/*     */     
/* 174 */     assertEquals("link size = staged size", Long.valueOf(staged.getSize()), Long.valueOf(linked.getSize()));
/* 175 */     assertTrue("link content = mime content", bytesEqual(mimeBytes, readInputStream(linked.getLocalBlob().getInputStream())));
/*     */     
/* 177 */     assertEquals("mblob size = staged size", Long.valueOf(staged.getSize()), Long.valueOf(fetched.getSize()));
/* 178 */     assertTrue("mailboxblob content = mime content", bytesEqual(mimeBytes, readInputStream(fetched.getLocalBlob().getInputStream())));
/*     */   }
/*     */   
/*     */   private Stats basicPerfTest(int numBlobs, int blobSize, boolean checkBlobs) throws Exception {
/* 182 */     Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(AccountTestUtil.getAccount(this.USER_NAME));
/* 183 */     StoreManager sm = StoreManager.getInstance();
/* 184 */     List<ParsedMessage> msgs = new ArrayList();
/* 185 */     int count = numBlobs;
/* 186 */     for (int i = 0; i < count; i++) {
/* 187 */       msgs.add(getMessage(blobSize));
/*     */     }
/* 189 */     List<Blob> incoming = new ArrayList();
/* 190 */     ZimbraLog.store.info("starting store incoming loop");
/* 191 */     long start = System.currentTimeMillis();
/* 192 */     for (ParsedMessage msg : msgs) {
/* 193 */       incoming.add(sm.storeIncoming(msg.getRawInputStream()));
/*     */     }
/* 195 */     long incomingTime = System.currentTimeMillis() - start;
/*     */     
/* 197 */     List<StagedBlob> staged = new ArrayList();
/* 198 */     ZimbraLog.store.info("starting stage loop");
/* 199 */     start = System.currentTimeMillis();
/* 200 */     for (Blob blob : incoming) {
/* 201 */       staged.add(sm.stage(blob, mbox));
/*     */     }
/* 203 */     long stageTime = System.currentTimeMillis() - start;
/*     */     
/* 205 */     List<MailboxBlob> linked = new ArrayList();
/* 206 */     ZimbraLog.store.info("starting link loop");
/* 207 */     start = System.currentTimeMillis();
/* 208 */     int i = 0;
/* 209 */     for (StagedBlob blob : staged) {
/* 210 */       linked.add(sm.link(blob, mbox, i++, 1));
/*     */     }
/* 212 */     long linkTime = System.currentTimeMillis() - start;
/*     */     
/* 214 */     List<MailboxBlob> fetched = new ArrayList();
/* 215 */     ZimbraLog.store.info("starting fetch loop");
/* 216 */     start = System.currentTimeMillis();
/* 217 */     i = 0;
/* 218 */     for (MailboxBlob mblob : linked) {
/* 219 */       fetched.add(sm.getMailboxBlob(mbox, i++, 1, mblob.getLocator()));
/*     */     }
/* 221 */     long fetchTime = System.currentTimeMillis() - start;
/* 222 */     if (checkBlobs) {
/* 223 */       for (i = 0; i < count; i++) {
/* 224 */         checkBlob((ParsedMessage)msgs.get(i), (Blob)incoming.get(i), (StagedBlob)staged.get(i), (MailboxBlob)linked.get(i), (MailboxBlob)fetched.get(i), mbox);
/*     */       }
/*     */     }
/*     */     
/* 228 */     ZimbraLog.store.info("starting delete loop");
/* 229 */     start = System.currentTimeMillis();
/* 230 */     for (MailboxBlob mblob : fetched) {
/* 231 */       sm.delete(mblob);
/*     */     }
/* 233 */     long deleteTime = System.currentTimeMillis() - start;
/*     */     
/* 235 */     Stats stats = new Stats(numBlobs, incomingTime, stageTime, linkTime, fetchTime, deleteTime, null);
/* 236 */     return stats;
/*     */   }
/*     */   
/*     */   private boolean createAccountIfNeeded() throws ServiceException {
/* 240 */     if (AccountTestUtil.accountExists(this.USER_NAME)) {
/* 241 */       return false;
/*     */     }
/* 243 */     ZimbraLog.store.info("creating account for test");
/* 244 */     Provisioning.getInstance().createAccount(AccountTestUtil.getAddress(this.USER_NAME), "test123", null);
/* 245 */     return true;
/*     */   }
/*     */   
/*     */   private void deleteAccount() throws ServiceException {
/* 249 */     Account acct = AccountTestUtil.getAccount(this.USER_NAME);
/* 250 */     MailboxManager.getInstance().getMailboxByAccount(acct).deleteMailbox();
/* 251 */     Provisioning.getInstance().deleteAccount(acct.getId());
/*     */   }
/*     */   
/*     */   public synchronized Element handle(Element request, Map<String, Object> context) throws ServiceException
/*     */   {
/* 256 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/* 257 */     Element response = zsc.createElement(AdminConstants.VERIFY_STORE_MANAGER_RESPONSE);
/*     */     
/* 259 */     boolean created = createAccountIfNeeded();
/*     */     try {
/*     */       try {
/* 262 */         ZimbraLog.store.info("verifying basic store functionality");
/* 263 */         testStore();
/*     */       } catch (Exception e) {
/* 265 */         throw ServiceException.FAILURE("store verification failed", e);
/*     */       }
/* 267 */       int blobSize = request.getAttributeInt("fileSize", 1024);
/*     */       try {
/* 269 */         ZimbraLog.store.info("running perf sanity tests");
/* 270 */         Stats stats = basicPerfTest(request.getAttributeInt("num", 1000), blobSize, request.getAttributeBool("checkBlobs", true));
/*     */         
/* 272 */         response.addAttribute("storeManagerClass", StoreManager.getInstance().getClass().getName()).addAttribute("incomingTime", stats.incomingTime).addAttribute("stageTime", stats.stageTime).addAttribute("linkTime", stats.linkTime).addAttribute("fetchTime", stats.fetchTime).addAttribute("deleteTime", stats.deleteTime);
/*     */ 
/*     */       }
/*     */       catch (Exception e)
/*     */       {
/* 277 */         throw ServiceException.FAILURE("perf sanity test failed", e);
/*     */       }
/*     */       catch (OutOfMemoryError oome) {
/* 280 */         throw ServiceException.FAILURE("OOME during perf test, with blob size " + blobSize + ". May need to use a smaller blob size or increase heap space", oome);
/*     */       }
/*     */     }
/*     */     finally {
/* 284 */       ZimbraLog.store.info("deleting account for test");
/* 285 */       if (created) {
/* 286 */         deleteAccount();
/*     */       }
/*     */     }
/* 289 */     return response;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/admin/VerifyStoreManager.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */